#include <websocketpp/config/asio_no_tls_client.hpp>
#include <websocketpp/client.hpp>
#include <iostream>
#include <chrono>
#include <thread>
using websocketpp::lib::bind;
using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;

typedef websocketpp::client<websocketpp::config::asio_client> client;

// 定义消息处理器
void on_message(client *c, websocketpp::connection_hdl hdl, client::message_ptr msg)
{
    std::cout << "Received: " << msg->get_payload() << std::endl;
}

int main()
{
    client ws_client;

    // 初始化 ASIO
    ws_client.init_asio();

    // 设置消息处理器
    ws_client.set_message_handler(bind(&on_message, &ws_client, ::_1, ::_2));

    // 连接错误处理器
    ws_client.set_fail_handler([](websocketpp::connection_hdl hdl)
                               { std::cerr << "Connection failed!" << std::endl; });

    // 创建连接对象
    websocketpp::lib::error_code ec;
    auto conn = ws_client.get_connection("ws://localhost:9002", ec);
    if (ec)
    {
        std::cerr << "Connection error: " << ec.message() << std::endl;
        return 1;
    }

    // 连接服务器
    ws_client.connect(conn);

    // 启动异步事件循环
    std::thread t([&ws_client]()
                  { ws_client.run(); });

    // 发送消息
    uint8_t count = 0;
    uint8_t data[8] = {0, 1, 2, 3, 4, 5, 6, 7};
    while (true)
    {
        // 发送二进制数据
        data[0] = count++;
        websocketpp::lib::error_code ec;
        ws_client.send(conn->get_handle(), data, sizeof(data), websocketpp::frame::opcode::binary, ec);
        if (ec)
        {
            std::cerr << "Send failed: " << ec.message() << std::endl;
        }
        else
        {
            char buf[64] = "";
            snprintf(buf, sizeof(buf), "Send: %x %x %x %x %x %x %x %x\n", data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]);
            printf("%s", buf);
        }
        // 延时 2 秒
        std::this_thread::sleep_for(std::chrono::seconds(2));
    }

    // 关闭连接
    ws_client.close(conn->get_handle(), websocketpp::close::status::normal, "");
    t.join();

    return 0;
}